/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pv1682010.gui;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pv1682010.User;

/**
 *
 * @author Isamaru
 */
public class ChangesTable {
    Logger log = LoggerFactory.getLogger(ChangesTable.class);
    private final TreeMap<User, Integer> set = new TreeMap<User,Integer>();

    public static final int EXISTS = 1;
    public static final int CHANGED = 2;
    public static final int NEW = 4;
    public static final int DELETED = 8;
    public static final int DELETED_NEW = 16;

    private boolean changed = false;

    private Integer put(User user, int value) {
	switch (value) {
	    case EXISTS:
		break;
	    case NEW:
	    case CHANGED:
	    case DELETED:
	    case DELETED_NEW:		
		changed = true;		
		break;
	    default:
		throw new IllegalArgumentException("value");
	}
	return set.put(user, value);
    }

    public Integer get(User user) {
	return set.get(user);
    }

    public void clear(List<User> list) {
	set.clear();
	changed = false;
	for (User user: list) {
	    set.put(user, EXISTS);
	}
    }

    public boolean changed() {
	return changed;
    }

    public void change(User user) {
	if (get(user) == EXISTS) {
	    put(user, CHANGED);
	}
    }

    boolean exists(User user) {
	Integer value = set.get(user);
	return !(value == null || value == DELETED);
    }

    void add(User user) {
	if (exists(user)) {
	    throw new IllegalArgumentException("User already exists!");
	}
	if (set.remove(user) == null) {
	    put(user, NEW);
	} else {
	    put(user, DELETED_NEW);
	}
    }

    void delete(User user) {
	if (!exists(user)) {
	    throw new IllegalArgumentException("User does not exist!");
	}
	put(user,DELETED);
    }

    List<User> filter(int filter) {
	List<User> list = new LinkedList<User>();
	for (User user : set.navigableKeySet()) {
	    if ((set.get(user) & filter) > 0) {
		list.add(user);
	    }
	}
	return Collections.unmodifiableList(list);
    }

    List<User> getChanged() {
	return filter(CHANGED);
    }

    List<User> getNew() {
	return filter(NEW + DELETED_NEW);
    }

    List<User> getDeleted() {
	return filter(DELETED + DELETED_NEW);
    }


    @Override
    public String toString() {
	return set.toString();
    }

}
